#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
# @Time    : 2022/8/14 17:35
# @File    : downloader.py
# @Software: PyCharm
"""
"""
import json
import os
from collections import OrderedDict
from concurrent import futures
from os.path import exists
from threading import Thread
import re
import requests
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Inches
from docx.shared import Pt, RGBColor
from tqdm import tqdm
from urllib3 import encode_multipart_formdata
import traceback


class Dairy:
    def __init__(self):
        config = json.load(open('config.json', 'r', encoding='gbk'))
        self.email = config['账号']
        self.passwd = config['密码']
        self.delete_img = config['是否删除图片']
        self.delete_txt = config['是否删除文字']
        self.boundary = '--d0d31fad-c0b8-457d-b73d-4ad625fab36e'
        self.Doc = Document()
        self.Doc.styles['Normal'].font.name = u'宋体'
        self.Doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
        self.Doc.styles['Normal'].font.size = Pt(10.5)
        self.Doc.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0)

    def login(self):
        params = OrderedDict([
            ("email", (None, self.email, None)),
            ("password", (None, self.passwd, None)),
        ])
        m = encode_multipart_formdata(params, boundary=self.boundary)
        headers = {
            'Host': 'nideriji.cn',
            'auth': 'token null',
            'user-agent': 'OhApp/2.9.7 Platform/Android',
            'content-type': m[1],
        }
        response = requests.post('https://nideriji.cn/api/login/', headers=headers, data=m[0])
        res = json.loads(response.text)
        self.token = res['token']
        self.userid = res['userid']
        self.username = res['user_config']['name']
        print('登录成功')

    def sync(self):
        params = OrderedDict([
            ("user_config_ts", (None, '0', None)),
            ("diaries_ts", (None, '0', None)),
            ("readmark_ts", (None, '0', None)),
            ("images_ts", (None, '0', None)),
        ])
        m = encode_multipart_formdata(params, boundary='--d0d31fad-c0b8-457d-b73d-4ad625fab36e')

        headers = {
            'Host': 'nideriji.cn',
            'auth': f'token {self.token}',
            'user-agent': 'OhApp/2.9.7 Platform/Android',
            'content-type': m[1],
        }

        response = requests.post('https://nideriji.cn/api/v2/sync/', headers=headers, data=m[0])
        res = json.loads(response.text)
        diaries = res['diaries']
        # 得到所有日记的id
        self.diary = []
        for i in diaries:
            self.diary.append(i['id'])
        # 获得图片最低索引
        self.imgtotal = -1 if len(res['images']) == 0 else res['images'][-1]['image_id']
        # 获得最新日记的时间
        self.newest = diaries[0]['createddate']
        self.docsave = f'{self.username} {self.newest}'
        self.imgsave = f'{self.username}_img'
        self.txtsave = f'{self.username}_txt'
        # 如果删除存档 则在这里删除文件夹下的文件
        if self.delete_txt and exists(f'{self.txtsave}'):
            for txt in os.listdir(f'{self.txtsave}'):
                os.remove(f'{self.txtsave}/{txt}')
        if self.delete_img and exists(f'{self.imgsave}'):
            for img in os.listdir(f'{self.imgsave}'):
                os.remove(f'{self.imgsave}/{img}')
        print('同步成功')

    def __getimg(self, num):
        if not exists(self.imgsave):
            os.mkdir(self.imgsave)
        if exists(f'{self.imgsave}/{num}.jpg'):
            # print(f'{self.imgpath}/{num}.jpg already exist')
            pass
        else:
            headers = {
                'Host': 'f.nideriji.cn',
                'user-agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; MuMu Build/V417IR)',
                'auth': f'token {self.token}'
            }
            response = requests.get(f'https://f.nideriji.cn/api/image/{self.userid}/{num}/', headers=headers)
            # print(self.userid)
            if response.text == '':
                # print(f'{self.imgpath}/{num}.jpg do not exist')
                pass
            else:
                with open(f'{self.imgsave}/{num}.jpg', 'wb') as fp:
                    fp.write(response.content)
                # print(f'{self.imgpath}/{num}.jpg saved')

    def getimg(self):
        tasks = []
        with futures.ThreadPoolExecutor(max_workers=10) as pool:
            for n in range(self.imgtotal + 1):
                tasks.append(pool.submit(self.__getimg, n))
            for _ in tqdm(futures.as_completed(tasks), total=len(tasks), desc='获取图片'):
                pass

    def _getcontent(self, id: str):
        params = OrderedDict([
            ("diary_ids", (None, id, None)),
        ])
        m = encode_multipart_formdata(params, boundary=self.boundary)

        headers = {
            'Host': 'nideriji.cn',
            'auth': f'token {self.token}',
            'user-agent': 'OhApp/2.9.7 Platform/Android',
            'content-type': m[1],
        }
        response = requests.post(f'https://nideriji.cn/api/diary/all_by_ids/{self.userid}/', headers=headers, data=m[0])
        # response.encoding
        res = json.loads(response.text)
        content = res['diaries'][0]
        title = content['title']
        createddate = content['createddate']
        mood = content['mood']
        weather = content['weather']
        text = content['content']
        if not exists(self.txtsave):
            os.mkdir(self.txtsave)
        if exists(f'{self.txtsave}/{createddate}.txt'):
            return
        with open(f"{self.txtsave}/{createddate}.txt", 'w', encoding=response.encoding) as fp:
            fp.write(f'{createddate} {title}\t{weather} {mood}\n')
            fp.write(text)

    def getcontent(self):
        tasks = []
        with futures.ThreadPoolExecutor(max_workers=4) as pool:
            for n in self.diary:
                tasks.append(pool.submit(self._getcontent, n))
            for _ in tqdm(futures.as_completed(tasks), total=len(tasks), desc='获取日记文本'):
                pass

    def write(self):
        files = os.listdir(f'{self.txtsave}')
        files.reverse()
        findimage = re.compile('\[图(.*)?\]')
        for file in tqdm(files, desc='将图片文字保存到docx文档'):
            with open(f'{self.txtsave}/{file}', 'r', encoding='utf-8') as fp:
                title = fp.readline()
                content = fp.read()

                para_heading = self.Doc.add_heading('', level=1)  # 返回1级标题段落对象，标题也相当于一个段落
                run = para_heading.add_run(title)
                run.font.name = u'宋体'  # 设置为宋体
                run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')  # 设置为宋体，和上边的一起使用
                run.font.size = Pt(15)  # 设置1级标题文字的大小为“小四” 为12磅
                # 写入正文 首先按照换行符分割
                content_list = content.split('\n')
                for line in content_list:
                    if '[' in line and ']' in line and '图' in line:
                        res = re.findall(findimage, line)
                        if len(res) >= 1:
                            res = res[0]
                        else:
                            continue
                        if exists(f'{self.imgsave}/{res}.jpg'):
                            # 图片居中设置
                            paragraph = self.Doc.add_paragraph()
                            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                            run = paragraph.add_run("")
                            run.add_picture(f'{self.imgsave}/{res}.jpg', width=Inches(3))
                        else:
                            p = self.Doc.add_paragraph('不存在图片或者已被删除 ╮(╯▽╰)╭')
                            p_format = p.paragraph_format
                            p_format.line_spacing = Pt(15)  # 行距
                    else:
                        try:
                            p = self.Doc.add_paragraph(line)
                            p_format = p.paragraph_format
                            p_format.line_spacing = Pt(15)  # 行距
                        except ValueError:
                            temp = re.findall(
                                '[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b\u4e00-\u9fa5]',
                                line)
                            temp = ''.join(temp)
                            p = self.Doc.add_paragraph(temp)
                            p_format = p.paragraph_format
                            p_format.line_spacing = Pt(15)  # 行距
        self.Doc.save(f'{self.docsave}.docx')
        print('docx文档已保存')

    """
    def insert(self):
        print('inserting img')
        self.old_doc = Document(f'{self.docsave} 纯文字.docx')
        self.new_doc = Document()
        self.new_doc.styles['Normal'].font.name = u'宋体'
        self.new_doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
        self.new_doc.styles['Normal'].font.size = Pt(10.5)
        self.new_doc.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0)
        # findimage = re.compile('\[图(.*)?\]')

        for paragraph in tqdm(self.old_doc.paragraphs):
            if str(paragraph.style.name) == "Heading 1":
                self.new_doc.add_paragraph(paragraph.text, style='Heading 1')
            else:
                lines = paragraph.text.split('\n')
                for line in lines:
                    if len(line) != 0 and line[0] == '[' and line[-1] == ']' and line[1] == '图':
                        # res = re.findall(findimage, line)
                        res = line[2:-1]
                        # 图片居中设置
                        paragraph = self.new_doc.add_paragraph()
                        paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
                        run = paragraph.add_run("")
                        run.add_picture(f'{self.imgsave}/{res}.jpg', width=Inches(4))
                    else:
                        p = self.new_doc.add_paragraph(line)
                        p_format = p.paragraph_format
                        p_format.line_spacing = Pt(18)  # 行距
        self.new_doc.save(f'{self.docsave}.docx')
        print('new docx saved')
        # 转换pdf
        # inputFile = f'{self.docsave}.docx'
        # outputFile = f'{self.docsave}.pdf'
        # file = open(outputFile, "w")
        # file.close()
        # print('converting docx to pdf')
        # docx2pdf.convert(inputFile, outputFile)
    """

    def run(self):
        try:
            self.login()
            self.sync()
            thread_img = Thread(target=self.getimg, args=())
            thread_txt = Thread(target=self.getcontent, args=())
            thread_img.start()
            thread_txt.start()
            # my.getimg()
            # my.getcontent()
            while thread_txt.is_alive() or thread_img.is_alive():
                # print(thread_txt.is_alive(), thread_img.is_alive())
                continue
            self.write()
            # my.insert()
            print('程序结束 任意按键退出')
            input()
        except:
            # print(e)
            # print(e.__traceback__.tb_frame.f_globals["__file__"])  # 发生异常所在的文件
            # print(e.__traceback__.tb_lineno)  # 发生异常所在的行数
            traceback.print_exc()
            print('程序出错 任意按键退出')
            input()


if __name__ == '__main__':
    my = Dairy()
    my.run()
    # my.login()
    # my.sync()
    # my._getcontent('12489633')
